package com.csst.dao.impl;

import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Set;
import java.util.Map.Entry;

import javax.annotation.Resource;

import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.HibernateTemplate;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.csst.dao.DAO;

@Transactional
@SuppressWarnings("unchecked")
public abstract class DAOSupport<T> implements DAO<T> {
	
	protected HibernateTemplate template;
	private Class<T> entityClass=getSuperGenericType();
	private String entityName=entityClass.getName();
	//this 当前对象   customerDaoImpl.getScrollData();
	//
	@Transactional(readOnly=true,propagation=Propagation.NOT_SUPPORTED)
	private Class<T> getSuperGenericType(){
		Type type=this.getClass().getGenericSuperclass();
		ParameterizedType para=(ParameterizedType)type;
		//参数化类型数组   Customer.class Product.class 
		Type[] types=para.getActualTypeArguments();
		return (Class)types[0];
	}

	@Resource(name = "sessionFactory")
	public void setTemplate(SessionFactory factory) {
		this.template = new HibernateTemplate(factory);
	}
	
	
	@Transactional(readOnly=true,propagation=Propagation.NOT_SUPPORTED)
	public long getCount() {
		return (Long)template.find("select count(o) from "+entityName+" o").get(0);
	}

	public void save(T entity) {
		template.saveOrUpdate(entity);
	}

	public void update(T entity) {
		template.merge(entity);
		
	}
	
	public void delete(Serializable... entityIDs) {
		for (Serializable entityID : entityIDs) {
			this.template.delete(template.get(entityClass, entityID));
		}
	}

	/**
	 * 删选 ，排序  select * from customer order by custname desc , custID asc 
	 * String, String  HashMap<String,String>  
	 * where objectParam
	 */
	@Transactional(readOnly=true,propagation=Propagation.NOT_SUPPORTED)
	public List<T> getScrollData(final int firstResult, final int maxResult,LinkedHashMap<String, String> orderBy) {
		  String orderby=generateOrderBy(orderBy);
		  final String hql="select o from "+entityName+" o "+orderby;
			return template.executeFind(new HibernateCallback() {
				public Object doInHibernate(Session session)
						throws HibernateException, SQLException {
					Query query=session.createQuery(hql);
					if (firstResult!=-1&&maxResult!=-1) {
						query.setFirstResult(firstResult).setMaxResults(maxResult);
					}
					return query.list();
			}
      });
	}
	
	@Transactional(readOnly=true,propagation=Propagation.NOT_SUPPORTED)
	public List<T> getScrollData(final int firstResult, final int maxResult) {
		return getScrollData(firstResult,maxResult,null);
	}
	

	@Transactional(readOnly=true,propagation=Propagation.NOT_SUPPORTED)
	private String generateOrderBy(HashMap<String, String> orderBy) {
		StringBuffer order=null;
		String orderstr="";
		if (orderBy!=null&&orderBy.size()>0) {
			Set<Entry<String, String>>  entrySet=orderBy.entrySet();
			if(entrySet.size()>0){
				order=new StringBuffer(" order by ");
				for (Entry<String, String> entry : entrySet) {
					order.append(" "+entry.getKey()+" "+entry.getValue()+" ,");
				}
				orderstr=order.toString().substring(0, order.toString().length()-1);
			}
		}
		
		
		return orderstr;
	}
	
	public T getById(Serializable entityID){
		
		return template.get(entityClass, entityID);
	}
	

}
